<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
                      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
    <title>Using Plugins - Zend Framework Manual</title>

    <link href="../css/shCore.css" rel="stylesheet" type="text/css" />
    <link href="../css/shThemeDefault.css" rel="stylesheet" type="text/css" />
    <link href="../css/styles.css" media="all" rel="stylesheet" type="text/css" />
</head>
<body>
<h1>Zend Framework</h1>
<h2>Programmer's Reference Guide</h2>
<ul>
    <li><a href="../en/learning.plugins.usage.html">Inglês (English)</a></li>
    <li><a href="../pt-br/learning.plugins.usage.html">Português Brasileiro (Brazilian Portuguese)</a></li>
</ul>
<table width="100%">
    <tr valign="top">
        <td width="85%">
            <table width="100%">
                <tr>
                    <td width="25%" style="text-align: left;">
                    <a href="learning.plugins.intro.html">Introduction</a>
                    </td>

                    <td width="50%" style="text-align: center;">
                        <div class="up"><span class="up"><a href="learning.plugins.html">Plugins in Zend Framework</a></span><br />
                        <span class="home"><a href="manual.html">Programmer's Reference Guide</a></span></div>
                    </td>

                    <td width="25%" style="text-align: right;">
                        <div class="next" style="text-align: right; float: right;"><a href="learning.plugins.conclusion.html">Conclusion</a></div>
                    </td>
                </tr>
            </table>
<hr />
<div id="learning.plugins.usage" class="section"><div class="info"><h1 class="title">Using Plugins</h1></div>
    

    <p class="para">
        Components that make use of plugins typically use
        <span class="classname">Zend_Loader_PluginLoader</span> to do their work. This class has you
        register plugins by specifying one or more &quot;prefix paths&quot;. The component will then call the
        PluginLoader&#039;s  <span class="methodname">load()</span> method, passing the plugin&#039;s short name to
        it. The PluginLoader will then query each prefix path to see if a class matching that short
        name exists. Prefix paths are searched in LIFO (last in, first out) order, so it will match
        those prefix paths registered last first -- allowing you to override existing plugins.
    </p>

    <p class="para">
        Some examples will make all of this more clear.
    </p>

    <div class="example" id="learning.plugins.usage.basic"><div class="info"><p><b>Example #1 Basic Plugin Example: Adding a single prefix path</b></p></div>
        

        <div class="example-contents"><p>
            In this example, we will assume some validators have been written and placed in the
            directory <var class="filename">foo/plugins/validators/</var>, and that all these classes share
            the class prefix &quot;Foo_Validate_&quot;; these two bits of information form our &quot;prefix path&quot;.
            Furthermore, let&#039;s assume we have two validators, one named &quot;Even&quot; (ensuring a number to
            be validated is even), and another named &quot;Dozens&quot; (ensuring the number is a multiple of
            12). The tree might look like this:
        </p></div>

        <pre class="programlisting brush: text">
foo/
|-- plugins/
|   |-- validators/
|   |   |-- Even.php
|   |   |-- Dozens.php
</pre>


        <div class="example-contents"><p>
            Now, we&#039;ll inform a <span class="classname">Zend_Form_Element</span> instance of this prefix
            path. <span class="classname">Zend_Form_Element</span>&#039;s
             <span class="methodname">addPrefixPath()</span> method expects a third argument that indicates
            the type of plugin for which the path is being registered; in this case, it&#039;s a
            &quot;validate&quot; plugin.
        </p></div>

        <pre class="programlisting brush: php">
$element-&gt;addPrefixPath(&#039;Foo_Validate&#039;, &#039;foo/plugins/validators/&#039;, &#039;validate&#039;);
</pre>


        <div class="example-contents"><p>
            Now we can simply tell the element the short name of the validators we want to use. In
            the following example, we&#039;re using a mix of standard validators (&quot;NotEmpty&quot;, &quot;Int&quot;) and
            custom validators (&quot;Even&quot;, &quot;Dozens&quot;):
        </p></div>

        <pre class="programlisting brush: php">
$element-&gt;addValidator(&#039;NotEmpty&#039;)
        -&gt;addValidator(&#039;Int&#039;)
        -&gt;addValidator(&#039;Even&#039;)
        -&gt;addValidator(&#039;Dozens&#039;);
</pre>


        <div class="example-contents"><p>
            When the element needs to validate, it will then request the plugin class from the
            PluginLoader. The first two validators will resolve to
            <span class="classname">Zend_Validate_NotEmpty</span> and
            <span class="classname">Zend_Validate_Int</span>, respectively; the next two will resolve to
            <span class="classname">Foo_Validate_Even</span> and <span class="classname">Foo_Validate_Dozens</span>,
            respectively.
        </p></div>
    </div>

    <blockquote class="note"><p><b class="note">Note</b>: <span class="info"><b>What happens if a plugin is not found?</b><br /></span>
        

        <p class="para">
            What happens if a plugin is requested, but the PluginLoader is unable to find a class
            matching it? For instance, in the above example, if we registered the plugin &quot;Bar&quot; with
            the element, what would happen?
        </p>

        <p class="para">
            The plugin loader will look through each prefix path, checking to see if a file matching
            the plugin name is found on that path. If the file is not found, it then moves on to the
            next prefix path.
        </p>

        <p class="para">
            Once the stack of prefix paths has been exhausted, if no matching file has been found,
            it will throw a <span class="exceptionname">Zend_Loader_PluginLoader_Exception</span>.
        </p>
    </p></blockquote>

    <div class="example" id="learning.plugins.usage.override"><div class="info"><p><b>Example #2 Intermediate Plugin Usage: Overriding existing plugins</b></p></div>
        

        <div class="example-contents"><p>
            One strength of the PluginLoader is that its use of a LIFO stack allows you to override
            existing plugins by creating your own versions locally with a different prefix path, and
            registering that prefix path later in the stack.
        </p></div>

        <div class="example-contents"><p>
            For example, let&#039;s consider <span class="classname">Zend_View_Helper_FormButton</span> (view
            helpers are one form of plugin). This view helper accepts three arguments, an element
            name (also used as the element&#039;s DOM identifier), a value (used as the button label),
            and an optional array of attributes. The helper then generates <acronym class="acronym">HTML</acronym>
            markup for a form input element.
        </p></div>

        <div class="example-contents"><p>
            Let&#039;s say you want the helper to instead generate a true <acronym class="acronym">HTML</acronym>
            <b><tt>button</tt></b> element; don&#039;t want the helper to generate a DOM identifier,
            but instead use the value for a CSS class selector; and that you have no interest in
            handling arbitrary attributes. You could accomplish this in a couple of ways. In both
            cases, you&#039;d create your own view helper class that implements the behavior you want;
            the difference is in how you would name and invoke them.
        </p></div>

        <div class="example-contents"><p>
            Our first example will be to name the element with a unique name:
            <span class="classname">Foo_View_Helper_CssButton</span>, which implies the plugin name
            &quot;CssButton&quot;. While this certainly is a viable approach, it poses several issues: if
            you&#039;ve already used the Button view helper in your code, you now have to refactor;
            alternately, if another developer starts writing code for your application, they may
            inadvertently use the Button view helper instead of your new view helper.
        </p></div>

        <div class="example-contents"><p>
            So, the better example is to use the plugin name &quot;Button&quot;, giving us the class name
            <span class="classname">Foo_View_Helper_Button</span>. We then register the prefix path with the
            view:
        </p></div>

        <pre class="programlisting brush: php">
// Zend_View::addHelperPath() utilizes the PluginLoader; however, it inverts
// the arguments, as it provides a default value of &quot;Zend_View_Helper&quot; for the
// plugin prefix.
//
// The below assumes your class is in the directory &#039;foo/view/helpers/&#039;.
$view-&gt;addHelperPath(&#039;foo/view/helpers&#039;, &#039;Foo_View_Helper&#039;);
</pre>


        <div class="example-contents"><p>
            Once done, anywhere you now use the &quot;Button&quot; helper will delegate to your custom
            <span class="classname">Foo_View_Helper_Button</span> class!
        </p></div>
    </div>
</div>
        <hr />

            <table width="100%">
                <tr>
                    <td width="25%" style="text-align: left;">
                    <a href="learning.plugins.intro.html">Introduction</a>
                    </td>

                    <td width="50%" style="text-align: center;">
                        <div class="up"><span class="up"><a href="learning.plugins.html">Plugins in Zend Framework</a></span><br />
                        <span class="home"><a href="manual.html">Programmer's Reference Guide</a></span></div>
                    </td>

                    <td width="25%" style="text-align: right;">
                        <div class="next" style="text-align: right; float: right;"><a href="learning.plugins.conclusion.html">Conclusion</a></div>
                    </td>
                </tr>
            </table>
</td>
        <td style="font-size: smaller;" width="15%"> <style type="text/css">
#leftbar {
	float: left;
	width: 186px;
	padding: 5px;
	font-size: smaller;
}
ul.toc {
	margin: 0px 5px 5px 5px;
	padding: 0px;
}
ul.toc li {
	font-size: 85%;
	margin: 1px 0 1px 1px;
	padding: 1px 0 1px 11px;
	list-style-type: none;
	background-repeat: no-repeat;
	background-position: center left;
}
ul.toc li.header {
	font-size: 115%;
	padding: 5px 0px 5px 11px;
	border-bottom: 1px solid #cccccc;
	margin-bottom: 5px;
}
ul.toc li.active {
	font-weight: bold;
}
ul.toc li a {
	text-decoration: none;
}
ul.toc li a:hover {
	text-decoration: underline;
}
</style>
 <ul class="toc">
  <li class="header home"><a href="manual.html">Programmer's Reference Guide</a></li>
  <li class="header up"><a href="manual.html">Programmer's Reference Guide</a></li>
  <li class="header up"><a href="learning.html">Learning Zend Framework</a></li>
  <li class="header up"><a href="learning.plugins.html">Plugins in Zend Framework</a></li>
  <li><a href="learning.plugins.intro.html">Introduction</a></li>
  <li class="active"><a href="learning.plugins.usage.html">Using Plugins</a></li>
  <li><a href="learning.plugins.conclusion.html">Conclusion</a></li>
 </ul>
 </td>
    </tr>
</table>

<script type="text/javascript" src="../js/shCore.js"></script>
<script type="text/javascript" src="../js/shAutoloader.js"></script>
<script type="text/javascript" src="../js/main.js"></script>

</body>
</html>